Skip to content

feat: support subtractive cell selection - #6476

Merged
KevinVandy merged 8 commits into
betafrom
agent/cell-selection-subtraction
Aug 1, 2026
Merged

feat: support subtractive cell selection#6476
KevinVandy merged 8 commits into
betafrom
agent/cell-selection-subtraction

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Jul 31, 2026

Copy link
Copy Markdown
Member

What

Adds ordered include/exclude operations to cell-selection state so consumers can represent selections such as “select all except this region” without rebuilding positive ranges themselves.

  • adds CellSelectionRange.operation and selectCellRange({ mode })
  • resolves ordered operations into deterministic, disjoint positive rectangles
  • makes modifier-click/drag subtract when it starts on a selected cell and include when it starts on an unselected cell
  • preserves the active operation while shrinking, Shift-extending, or keyboard-extending a range
  • keeps focused-cell state independent from whether that cell is selected
  • updates framework guides, generated API references, examples, and clipboard guidance
  • adds core geometry/feature coverage and React cell-selection/spreadsheet browser coverage

additive remains supported as a deprecated compatibility alias for mode: 'include'; an explicit mode takes precedence.

This implements the cell-selection model explored in discussion #6473.

Why

Cell-selection state previously described only a union of positive rectangles. Removing an arbitrary rectangle required application code to split and reconstruct ranges. Ordered include/exclude operations keep the controlled state compact while allowing Table to derive the final selection geometry consistently.

Verification

  • pnpm test — passed all 839 tasks
  • pnpm test:skills — validated all 80 skills
  • pnpm test:intent — validation and staleness scan passed
  • pnpm test:docs — passed
  • table-core focused tests — 57 files / 1,132 tests passed
  • React cell-selection E2E — 4/4 passed
  • React spreadsheet E2E — 12/12 passed
  • git diff --check — passed

Summary by CodeRabbit

  • New Features

    • Added inclusive and exclusive multi-range cell selection.
    • Ctrl/Cmd-clicking or dragging can add or subtract rectangular regions.
    • Programmatic selection supports replace, include, and exclude modes; the previous additive option remains supported for compatibility.
    • Selection, focus, counting, and copied data reflect final positive regions.
  • Documentation

    • Updated framework guides, API references, examples, and migration guidance.
  • Tests

    • Added coverage for subtractive selection, re-inclusion, keyboard extension, and geometry behavior.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ba2b180-171c-467e-a982-850c7ba9806d

📥 Commits

Reviewing files that changed from the base of the PR and between e877d0f and 55b025f.

📒 Files selected for processing (116)
  • .gitignore
  • examples/alpine/aggregation/package.json
  • examples/alpine/basic-app-table/package.json
  • examples/alpine/basic-create-table/package.json
  • examples/alpine/basic-dynamic-columns/package.json
  • examples/alpine/basic-external-atoms/package.json
  • examples/alpine/basic-external-state/package.json
  • examples/alpine/cell-selection/package.json
  • examples/alpine/column-ordering/package.json
  • examples/alpine/column-pinning-split/package.json
  • examples/alpine/column-pinning-sticky/package.json
  • examples/alpine/column-pinning/package.json
  • examples/alpine/column-resizing-performant/package.json
  • examples/alpine/column-resizing/package.json
  • examples/alpine/column-sizing/package.json
  • examples/alpine/column-visibility/package.json
  • examples/alpine/custom-plugin/package.json
  • examples/alpine/expanding/package.json
  • examples/alpine/filters-faceted-bucketed/package.json
  • examples/alpine/filters-faceted/package.json
  • examples/alpine/filters/package.json
  • examples/alpine/grouped-aggregation/package.json
  • examples/alpine/grouping/package.json
  • examples/alpine/header-groups/package.json
  • examples/alpine/pagination/package.json
  • examples/alpine/row-pinning/package.json
  • examples/alpine/row-selection/package.json
  • examples/alpine/sorting-dynamic-data/package.json
  • examples/alpine/sorting/package.json
  • examples/alpine/sub-components/package.json
  • examples/lit/aggregation/package.json
  • examples/lit/basic-app-table/package.json
  • examples/lit/basic-dynamic-columns/package.json
  • examples/lit/basic-external-atoms/package.json
  • examples/lit/basic-external-state/package.json
  • examples/lit/basic-subscribe/package.json
  • examples/lit/basic-table-controller/package.json
  • examples/lit/cell-selection/package.json
  • examples/lit/column-ordering/package.json
  • examples/lit/column-pinning-split/package.json
  • examples/lit/column-pinning-sticky/package.json
  • examples/lit/column-pinning/package.json
  • examples/lit/column-resizing-performant/package.json
  • examples/lit/column-resizing/package.json
  • examples/lit/column-visibility/package.json
  • examples/lit/composable-tables/package.json
  • examples/lit/expanding/package.json
  • examples/lit/filters-faceted-bucketed/package.json
  • examples/lit/filters-faceted/package.json
  • examples/lit/filters-fuzzy/package.json
  • examples/lit/filters/package.json
  • examples/lit/grouped-aggregation/package.json
  • examples/lit/grouping/package.json
  • examples/lit/header-groups/package.json
  • examples/lit/kitchen-sink/package.json
  • examples/lit/pagination/package.json
  • examples/lit/row-pinning/package.json
  • examples/lit/row-selection/package.json
  • examples/lit/sorting-dynamic-data/package.json
  • examples/lit/sorting/package.json
  • examples/lit/sub-components/package.json
  • examples/lit/virtualized-columns/package.json
  • examples/lit/virtualized-infinite-scrolling/package.json
  • examples/lit/virtualized-rows/package.json
  • examples/react/aggregation/package.json
  • examples/react/basic-dynamic-columns/package.json
  • examples/react/basic-external-atoms/package.json
  • examples/react/basic-external-state/package.json
  • examples/react/basic-subscribe/package.json
  • examples/react/basic-use-app-table/package.json
  • examples/react/basic-use-legacy-table/package.json
  • examples/react/basic-use-table/package.json
  • examples/react/cell-selection/package.json
  • examples/react/column-dnd/package.json
  • examples/react/column-ordering/package.json
  • examples/react/column-pinning-split/package.json
  • examples/react/column-pinning-sticky/package.json
  • examples/react/column-pinning/package.json
  • examples/react/column-resizing-performant/package.json
  • examples/react/column-resizing/package.json
  • examples/react/column-sizing/package.json
  • examples/react/column-visibility/package.json
  • examples/react/composable-tables/package.json
  • examples/react/custom-plugin/package.json
  • examples/react/expanding/package.json
  • examples/react/filters-faceted-bucketed/package.json
  • examples/react/filters-faceted/package.json
  • examples/react/filters-fuzzy/package.json
  • examples/react/filters/package.json
  • examples/react/grouped-aggregation/package.json
  • examples/react/grouping/package.json
  • examples/react/header-groups/package.json
  • examples/react/kitchen-sink-chakra-ui/package.json
  • examples/react/kitchen-sink-mantine/package.json
  • examples/react/kitchen-sink-material-ui/package.json
  • examples/react/mantine-react-table/package.json
  • examples/react/pagination/package.json
  • examples/react/row-dnd/package.json
  • examples/react/row-pinning/package.json
  • examples/react/row-selection/package.json
  • examples/react/sorting/package.json
  • examples/react/spreadsheet/package.json
  • examples/react/sub-components/package.json
  • examples/react/virtualized-columns-experimental/package.json
  • examples/react/virtualized-columns/package.json
  • examples/react/virtualized-infinite-scrolling/package.json
  • examples/react/virtualized-rows-experimental/package.json
  • examples/react/virtualized-rows/package.json
  • examples/react/with-tanstack-form/package.json
  • examples/react/with-tanstack-query/package.json
  • examples/react/with-tanstack-router/package.json
  • examples/vanilla/aggregation/package.json
  • examples/vanilla/basic/package.json
  • examples/vanilla/pagination/package.json
  • examples/vanilla/sorting/package.json
  • test-results/.last-run.json
💤 Files with no reviewable changes (1)
  • test-results/.last-run.json

📝 Walkthrough

Walkthrough

The cell-selection feature now supports ordered include/exclude operations, subtractive modified interactions, explicit range modes, normalized positive regions, and focused excluded cells. Documentation, examples, migration guidance, and tests describe or verify the behavior.

Changes

Cell selection operations

Layer / File(s) Summary
Selection contracts and public modes
packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts, docs/reference/index/...
Selection state records ordered operations. APIs support replace, include, and exclude modes. The deprecated additive option remains documented for compatibility.
Bounds geometry and resolution
packages/table-core/src/features/cell-selection/cellSelectionGeometry.ts, packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts, packages/table-core/tests/implementation/features/cell-selection/*
Rectangle operations normalize ordered ranges into disjoint positive regions. Selection counting, traversal, data retrieval, focus, and interaction handling use the resolved regions.
Guides, references, examples, and migration skills
docs/framework/*/guide/cell-selection.md, docs/reference/*, examples/*, packages/*/skills/*, _artifacts/*
Guides, API references, examples, skill files, and artifact metadata document subtractive interactions and final-region semantics. Lit examples also receive formatting-only changes.
End-to-end validation
examples/react/cell-selection/tests/e2e/smoke.spec.ts, examples/react/spreadsheet/tests/e2e/spreadsheet.spec.ts
Playwright tests verify subtracting a cell from a selected range, preserving focus on the excluded cell, and reporting no page errors.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • TanStack/table#6455: Extends the related cell-selection range model and APIs with ordered include/exclude operations.
  • TanStack/table#6457: Contains related subtractive cell-selection behavior and spreadsheet example coverage.

Suggested reviewers: tannerlinsley

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CellSelectionFeature
  participant CellSelectionGeometry
  participant SelectionState
  User->>CellSelectionFeature: Ctrl/Cmd-click or drag a cell range
  CellSelectionFeature->>CellSelectionGeometry: Apply include or exclude bounds
  CellSelectionGeometry-->>CellSelectionFeature: Return normalized positive regions
  CellSelectionFeature->>SelectionState: Store operation and focus anchor
  SelectionState-->>User: Expose selected and focused cell state
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: support for subtractive cell selection.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/cell-selection-subtraction

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Jul 31, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit e877d0f

Command Status Duration Result
nx affected --targets=test:eslint,test:sherif,t... ✅ Succeeded 6m 43s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 59s View ↗

☁️ Nx Cloud last updated this comment at 2026-08-01 12:28:33 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jul 31, 2026

Copy link
Copy Markdown
More templates

@tanstack/alpine-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/alpine-table@6476

@tanstack/angular-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table@6476

@tanstack/angular-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/angular-table-devtools@6476

@tanstack/ember-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/ember-table@6476

@tanstack/lit-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/lit-table@6476

@tanstack/match-sorter-utils

npm i https://pkg.pr.new/TanStack/table/@tanstack/match-sorter-utils@6476

@tanstack/octane-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/octane-table@6476

@tanstack/preact-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table@6476

@tanstack/preact-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/preact-table-devtools@6476

@tanstack/react-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table@6476

@tanstack/react-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/react-table-devtools@6476

@tanstack/solid-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table@6476

@tanstack/solid-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/solid-table-devtools@6476

@tanstack/svelte-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/svelte-table@6476

@tanstack/table-core

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-core@6476

@tanstack/table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/table-devtools@6476

@tanstack/vue-table

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table@6476

@tanstack/vue-table-devtools

npm i https://pkg.pr.new/TanStack/table/@tanstack/vue-table-devtools@6476

commit: 55b025f

@KevinVandy
KevinVandy marked this pull request as ready for review July 31, 2026 23:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts (1)

300-305: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

selectCellRange's range parameter accepts an operation field that has no effect.

The public selectCellRange signature types its range argument as the full CellSelectionRange, which includes the optional operation field. The implementation always discards that field and derives the actual operation solely from opts.mode, defaulting to replace when mode is omitted. A caller who sets range.operation: 'exclude' without also passing opts.mode: 'exclude' silently gets a full-selection replace instead of an exclusion. Narrow the public parameter type so this mismatch cannot compile, and keep the stripping logic as the single source of truth.

  • packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts#L300-L305: change the range parameter type on selectCellRange to Omit<CellSelectionRange, 'operation'>.
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts#L566-L572: once the type is narrowed, the { operation: _operation, ...coordinates } destructuring can be simplified since range will no longer carry an operation field to strip.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts`
around lines 300 - 305, Narrow the public selectCellRange parameter in
cellSelectionFeature.types.ts:300-305 to Omit<CellSelectionRange, 'operation'>
so callers cannot provide an ignored operation field. In
cellSelectionFeature.utils.ts:566-572, simplify the range destructuring to use
the coordinates directly because operation is no longer part of the accepted
range type, while preserving opts.mode as the sole operation source and existing
default behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/reference/index/interfaces/SelectCellRangeOptions.md`:
- Around line 29-38: Update the source JSDoc for SelectCellRangeOptions.mode in
the cell-selection type definitions to explicitly state that mode takes
precedence over the deprecated additive option when both are provided, including
that mode: 'exclude' remains subtractive with additive: true. Regenerate the
corresponding SelectCellRangeOptions reference page so the clarification is
reflected in the documentation.

In `@docs/reference/static-functions/functions/table_getCellSelectionBounds.md`:
- Around line 14-15: Update the description of the standalone function reference
for table_getCellSelectionBounds to explicitly state that the returned index
rectangles use inclusive boundaries, matching
Table_CellSelection.getCellSelectionBounds.

In `@docs/reference/static-functions/functions/table_getFocusedCell.md`:
- Line 16: Update the documentation for table_getFocusedCell to clarify that an
exclude operation may leave the focused cell outside the final positive
selection, so callers must not assume the returned cell is selected.

---

Outside diff comments:
In
`@packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts`:
- Around line 300-305: Narrow the public selectCellRange parameter in
cellSelectionFeature.types.ts:300-305 to Omit<CellSelectionRange, 'operation'>
so callers cannot provide an ignored operation field. In
cellSelectionFeature.utils.ts:566-572, simplify the range destructuring to use
the coordinates directly because operation is no longer part of the accepted
range type, while preserving opts.mode as the sole operation source and existing
default behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b1280804-87eb-4096-abfb-2feaa3e5d077

📥 Commits

Reviewing files that changed from the base of the PR and between ba53bca and 8b72f6f.

📒 Files selected for processing (65)
  • docs/framework/alpine/guide/cell-selection.md
  • docs/framework/angular/guide/cell-selection.md
  • docs/framework/ember/guide/cell-selection.md
  • docs/framework/lit/guide/cell-selection.md
  • docs/framework/lit/quick-start.md
  • docs/framework/preact/guide/cell-selection.md
  • docs/framework/react/guide/cell-selection.md
  • docs/framework/solid/guide/cell-selection.md
  • docs/framework/svelte/guide/cell-selection.md
  • docs/framework/vue/guide/cell-selection.md
  • docs/reference/index/index.md
  • docs/reference/index/interfaces/CellSelectionRange.md
  • docs/reference/index/interfaces/Cell_CellSelection.md
  • docs/reference/index/interfaces/SelectCellRangeOptions.md
  • docs/reference/index/interfaces/TableOptions_CellSelection.md
  • docs/reference/index/interfaces/Table_CellSelection.md
  • docs/reference/index/type-aliases/CellSelectionRangeMode.md
  • docs/reference/index/type-aliases/CellSelectionRangeOperation.md
  • docs/reference/index/type-aliases/CellSelectionState.md
  • docs/reference/static-functions/functions/cell_getIsFocused.md
  • docs/reference/static-functions/functions/cell_getIsSelected.md
  • docs/reference/static-functions/functions/table_getCellSelectionBounds.md
  • docs/reference/static-functions/functions/table_getFocusedCell.md
  • docs/reference/static-functions/functions/table_getSelectedCellCount.md
  • docs/reference/static-functions/functions/table_getSelectedCellRangesData.md
  • docs/reference/static-functions/functions/table_selectCellRange.md
  • examples/alpine/cell-selection/src/main.ts
  • examples/angular/cell-selection/src/app/app.html
  • examples/angular/cell-selection/src/app/app.ts
  • examples/lit/basic-app-table/src/main.ts
  • examples/lit/basic-dynamic-columns/src/main.ts
  • examples/lit/basic-external-atoms/src/main.ts
  • examples/lit/basic-external-state/src/main.ts
  • examples/lit/basic-subscribe/src/main.ts
  • examples/lit/cell-selection/src/main.ts
  • examples/lit/column-pinning-sticky/src/main.ts
  • examples/lit/column-pinning/src/main.ts
  • examples/lit/column-sizing/src/main.ts
  • examples/lit/composable-tables/src/components/products-table.ts
  • examples/lit/composable-tables/src/components/users-table.ts
  • examples/lit/expanding/src/main.ts
  • examples/lit/filters-faceted-bucketed/src/main.ts
  • examples/lit/filters-faceted/src/main.ts
  • examples/lit/filters-fuzzy/src/main.ts
  • examples/lit/filters/src/main.ts
  • examples/lit/grouped-aggregation/src/main.ts
  • examples/lit/grouping/src/main.ts
  • examples/lit/kitchen-sink/src/main.ts
  • examples/lit/row-pinning/src/main.ts
  • examples/lit/sorting-dynamic-data/src/main.ts
  • examples/lit/sorting/src/main.ts
  • examples/lit/virtualized-columns/src/main.ts
  • examples/preact/cell-selection/src/main.tsx
  • examples/react/cell-selection/src/main.tsx
  • examples/react/cell-selection/tests/e2e/smoke.spec.ts
  • examples/react/spreadsheet/tests/e2e/spreadsheet.spec.ts
  • examples/solid/cell-selection/src/App.tsx
  • examples/svelte/cell-selection/src/App.svelte
  • examples/vue/cell-selection/src/App.vue
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts
  • packages/table-core/src/features/cell-selection/cellSelectionGeometry.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionFeature.test.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionGeometry.test.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionRange.test.ts

Comment on lines +29 to +38
### mode?

```ts
optional mode: CellSelectionRangeMode;
```

Defined in: [features/cell-selection/cellSelectionFeature.types.ts:79](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts#L79)

Whether to replace the selection, add the range, or subtract the range.
Defaults to `replace`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document precedence when both options are provided.

mode takes precedence over the deprecated additive flag. State this explicitly so calls such as mode: 'exclude', additive: true are understood as subtractive.

Add the clarification to the source JSDoc and regenerate this reference page.

Proposed clarification
 Whether to replace the selection, add the range, or subtract the range.
 Defaults to `replace`.
+When provided, `mode` takes precedence over deprecated `additive`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/reference/index/interfaces/SelectCellRangeOptions.md` around lines 29 -
38, Update the source JSDoc for SelectCellRangeOptions.mode in the
cell-selection type definitions to explicitly state that mode takes precedence
over the deprecated additive option when both are provided, including that mode:
'exclude' remains subtractive with additive: true. Regenerate the corresponding
SelectCellRangeOptions reference page so the clarification is reflected in the
documentation.

Comment on lines +14 to +15
Resolves ordered range operations into disjoint, positive display-order
index rectangles.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document that the bounds are inclusive.

The standalone function reference omits the inclusive endpoint contract documented by Table_CellSelection.getCellSelectionBounds. Add it so consumers do not misread the rectangle boundaries.

Proposed clarification
-Resolves ordered range operations into disjoint, positive display-order
-index rectangles.
+Resolves ordered range operations into disjoint, positive, inclusive
+display-order index rectangles.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Resolves ordered range operations into disjoint, positive display-order
index rectangles.
Resolves ordered range operations into disjoint, positive, inclusive
display-order index rectangles.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/reference/static-functions/functions/table_getCellSelectionBounds.md`
around lines 14 - 15, Update the description of the standalone function
reference for table_getCellSelectionBounds to explicitly state that the returned
index rectangles use inclusive boundaries, matching
Table_CellSelection.getCellSelectionBounds.

Defined in: [features/cell-selection/cellSelectionFeature.utils.ts:510](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts#L510)

Returns the active cell, i.e. the anchor of the most recent range.
Returns the active cell, i.e. the anchor of the most recent operation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Document focus on excluded cells.

An exclude operation can leave the focused cell outside the final positive selection. Add this clarification so callers do not assume table_getFocusedCell() always returns a selected cell.

Proposed clarification
 Returns the active cell, i.e. the anchor of the most recent operation.
+An exclusion operation can leave the focused cell outside the final positive selection.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Returns the active cell, i.e. the anchor of the most recent operation.
Returns the active cell, i.e. the anchor of the most recent operation.
An exclusion operation can leave the focused cell outside the final positive selection.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/reference/static-functions/functions/table_getFocusedCell.md` at line
16, Update the documentation for table_getFocusedCell to clarify that an exclude
operation may leave the focused cell outside the final positive selection, so
callers must not assume the returned cell is selected.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/framework/solid/guide/cell-selection.md`:
- Line 210: Update the `cell.getIsSelected()` documentation to describe the
resolved selection state: it should indicate whether the cell belongs to the
final positive selection regions, not merely whether it falls within any stored
range, since excluded cells are not selected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: be9538f8-0aed-4d74-bfc9-bf6ede05dbbd

📥 Commits

Reviewing files that changed from the base of the PR and between ba53bca and 8b72f6f.

📒 Files selected for processing (65)
  • docs/framework/alpine/guide/cell-selection.md
  • docs/framework/angular/guide/cell-selection.md
  • docs/framework/ember/guide/cell-selection.md
  • docs/framework/lit/guide/cell-selection.md
  • docs/framework/lit/quick-start.md
  • docs/framework/preact/guide/cell-selection.md
  • docs/framework/react/guide/cell-selection.md
  • docs/framework/solid/guide/cell-selection.md
  • docs/framework/svelte/guide/cell-selection.md
  • docs/framework/vue/guide/cell-selection.md
  • docs/reference/index/index.md
  • docs/reference/index/interfaces/CellSelectionRange.md
  • docs/reference/index/interfaces/Cell_CellSelection.md
  • docs/reference/index/interfaces/SelectCellRangeOptions.md
  • docs/reference/index/interfaces/TableOptions_CellSelection.md
  • docs/reference/index/interfaces/Table_CellSelection.md
  • docs/reference/index/type-aliases/CellSelectionRangeMode.md
  • docs/reference/index/type-aliases/CellSelectionRangeOperation.md
  • docs/reference/index/type-aliases/CellSelectionState.md
  • docs/reference/static-functions/functions/cell_getIsFocused.md
  • docs/reference/static-functions/functions/cell_getIsSelected.md
  • docs/reference/static-functions/functions/table_getCellSelectionBounds.md
  • docs/reference/static-functions/functions/table_getFocusedCell.md
  • docs/reference/static-functions/functions/table_getSelectedCellCount.md
  • docs/reference/static-functions/functions/table_getSelectedCellRangesData.md
  • docs/reference/static-functions/functions/table_selectCellRange.md
  • examples/alpine/cell-selection/src/main.ts
  • examples/angular/cell-selection/src/app/app.html
  • examples/angular/cell-selection/src/app/app.ts
  • examples/lit/basic-app-table/src/main.ts
  • examples/lit/basic-dynamic-columns/src/main.ts
  • examples/lit/basic-external-atoms/src/main.ts
  • examples/lit/basic-external-state/src/main.ts
  • examples/lit/basic-subscribe/src/main.ts
  • examples/lit/cell-selection/src/main.ts
  • examples/lit/column-pinning-sticky/src/main.ts
  • examples/lit/column-pinning/src/main.ts
  • examples/lit/column-sizing/src/main.ts
  • examples/lit/composable-tables/src/components/products-table.ts
  • examples/lit/composable-tables/src/components/users-table.ts
  • examples/lit/expanding/src/main.ts
  • examples/lit/filters-faceted-bucketed/src/main.ts
  • examples/lit/filters-faceted/src/main.ts
  • examples/lit/filters-fuzzy/src/main.ts
  • examples/lit/filters/src/main.ts
  • examples/lit/grouped-aggregation/src/main.ts
  • examples/lit/grouping/src/main.ts
  • examples/lit/kitchen-sink/src/main.ts
  • examples/lit/row-pinning/src/main.ts
  • examples/lit/sorting-dynamic-data/src/main.ts
  • examples/lit/sorting/src/main.ts
  • examples/lit/virtualized-columns/src/main.ts
  • examples/preact/cell-selection/src/main.tsx
  • examples/react/cell-selection/src/main.tsx
  • examples/react/cell-selection/tests/e2e/smoke.spec.ts
  • examples/react/spreadsheet/tests/e2e/spreadsheet.spec.ts
  • examples/solid/cell-selection/src/App.tsx
  • examples/svelte/cell-selection/src/App.svelte
  • examples/vue/cell-selection/src/App.vue
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts
  • packages/table-core/src/features/cell-selection/cellSelectionGeometry.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionFeature.test.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionGeometry.test.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionRange.test.ts
🚧 Files skipped from review as they are similar to previous changes (62)
  • docs/framework/lit/quick-start.md
  • docs/reference/index/index.md
  • examples/lit/column-sizing/src/main.ts
  • examples/alpine/cell-selection/src/main.ts
  • examples/lit/basic-dynamic-columns/src/main.ts
  • docs/reference/index/interfaces/CellSelectionRange.md
  • examples/lit/filters-faceted/src/main.ts
  • examples/lit/expanding/src/main.ts
  • examples/lit/basic-external-state/src/main.ts
  • examples/lit/grouped-aggregation/src/main.ts
  • docs/reference/index/type-aliases/CellSelectionState.md
  • examples/lit/virtualized-columns/src/main.ts
  • docs/reference/static-functions/functions/cell_getIsSelected.md
  • examples/lit/row-pinning/src/main.ts
  • examples/vue/cell-selection/src/App.vue
  • examples/lit/column-pinning-sticky/src/main.ts
  • examples/lit/column-pinning/src/main.ts
  • docs/reference/static-functions/functions/cell_getIsFocused.md
  • examples/angular/cell-selection/src/app/app.ts
  • docs/reference/index/type-aliases/CellSelectionRangeOperation.md
  • examples/lit/filters-faceted-bucketed/src/main.ts
  • examples/lit/basic-external-atoms/src/main.ts
  • docs/reference/static-functions/functions/table_selectCellRange.md
  • examples/lit/sorting-dynamic-data/src/main.ts
  • docs/reference/index/interfaces/SelectCellRangeOptions.md
  • examples/angular/cell-selection/src/app/app.html
  • examples/lit/filters/src/main.ts
  • examples/lit/composable-tables/src/components/users-table.ts
  • docs/reference/static-functions/functions/table_getCellSelectionBounds.md
  • examples/react/spreadsheet/tests/e2e/spreadsheet.spec.ts
  • examples/lit/basic-subscribe/src/main.ts
  • examples/lit/composable-tables/src/components/products-table.ts
  • examples/solid/cell-selection/src/App.tsx
  • docs/reference/static-functions/functions/table_getSelectedCellRangesData.md
  • examples/lit/grouping/src/main.ts
  • examples/lit/sorting/src/main.ts
  • docs/reference/static-functions/functions/table_getFocusedCell.md
  • examples/react/cell-selection/src/main.tsx
  • examples/lit/filters-fuzzy/src/main.ts
  • examples/preact/cell-selection/src/main.tsx
  • examples/react/cell-selection/tests/e2e/smoke.spec.ts
  • examples/lit/cell-selection/src/main.ts
  • examples/svelte/cell-selection/src/App.svelte
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionRange.test.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionGeometry.test.ts
  • examples/lit/kitchen-sink/src/main.ts
  • examples/lit/basic-app-table/src/main.ts
  • packages/table-core/tests/implementation/features/cell-selection/cellSelectionFeature.test.ts
  • docs/framework/svelte/guide/cell-selection.md
  • docs/reference/static-functions/functions/table_getSelectedCellCount.md
  • docs/framework/alpine/guide/cell-selection.md
  • docs/framework/preact/guide/cell-selection.md
  • docs/reference/index/interfaces/TableOptions_CellSelection.md
  • docs/framework/vue/guide/cell-selection.md
  • docs/framework/lit/guide/cell-selection.md
  • docs/framework/ember/guide/cell-selection.md
  • docs/reference/index/interfaces/Table_CellSelection.md
  • docs/reference/index/interfaces/Cell_CellSelection.md
  • docs/framework/react/guide/cell-selection.md
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.types.ts
  • docs/framework/angular/guide/cell-selection.md
  • packages/table-core/src/features/cell-selection/cellSelectionFeature.utils.ts


TanStack Table does not dictate how you render selected cells. These cell APIs give you everything you need:

- `cell.getIsSelected()` - whether this cell falls inside any range

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Describe resolved selection state.

An excluded cell falls inside a stored range but is not selected. State that cell.getIsSelected() checks membership in the final positive selection regions.

Proposed fix
-- `cell.getIsSelected()` - whether this cell falls inside any range
+- `cell.getIsSelected()` - whether this cell falls inside a final positive selection region
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `cell.getIsSelected()` - whether this cell falls inside any range
- `cell.getIsSelected()` - whether this cell falls inside a final positive selection region
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/framework/solid/guide/cell-selection.md` at line 210, Update the
`cell.getIsSelected()` documentation to describe the resolved selection state:
it should indicate whether the cell belongs to the final positive selection
regions, not merely whether it falls within any stored range, since excluded
cells are not selected.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/table-core/skills/migrate-v8-to-v9/SKILL.md`:
- Line 298: Update the migration checklist wording around the stock feature
inventory so it still audits all 16 available features, but instructs
registering only those actually used by the migrated table’s table, row, column,
cell, and header code. Preserve the opt-in nature of v9 features and avoid
requiring unrelated registrations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5b6c3745-fd95-4c89-a64f-d7f92ed3daad

📥 Commits

Reviewing files that changed from the base of the PR and between 8b72f6f and e877d0f.

📒 Files selected for processing (12)
  • _artifacts/domain_map.yaml
  • _artifacts/skill_spec.md
  • _artifacts/skill_tree.yaml
  • packages/angular-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/lit-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/preact-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/react-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/solid-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/svelte-table/skills/migrate-v8-to-v9/SKILL.md
  • packages/table-core/skills/cell-selection/SKILL.md
  • packages/table-core/skills/migrate-v8-to-v9/SKILL.md
  • packages/vue-table/skills/migrate-v8-to-v9/SKILL.md

- [ ] Replace the v8 adapter constructor/hook/controller with its v9 entrypoint.
- [ ] Add a stable `features` object to every table.
- [ ] Inventory every feature API used by table, row, column, cell, and header code; register all 14 required stock features.
- [ ] Inventory every feature API used by table, row, column, cell, and header code; register all 16 required stock features.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Register only the features used by the migrated table.

Line 298 requires all 16 stock features, but v9 features are opt-in and stockFeatures is documented as an audit bridge. This wording can make migrations register unrelated state and APIs and lose tree-shaking. Change the checklist to audit all 16 features but register only the features used by the code.

Proposed wording
-- [ ] Inventory every feature API used by table, row, column, cell, and header code; register all 16 required stock features.
+- [ ] Inventory every feature API used by table, row, column, cell, and header code; register only the features used by that code, and audit all 16 stock features for migration coverage.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- [ ] Inventory every feature API used by table, row, column, cell, and header code; register all 16 required stock features.
- [ ] Inventory every feature API used by table, row, column, cell, and header code; register only the features used by that code, and audit all 16 stock features for migration coverage.
🧰 Tools
🪛 SkillSpector (2.4.4)

[warning] 180: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 180: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 182: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 182: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 183: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 184: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))


[warning] 234: [MP2] Context Window Stuffing: Skill attempts to fill the context window with filler content, displacing legitimate instructions and safety constraints. This can degrade agent performance or bypass safety boundaries.

Remediation: Implement context-window management that detects and rejects padding or stuffing attempts. Prioritize system instructions over user-injected content.

(Memory Poisoning (MP2))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/table-core/skills/migrate-v8-to-v9/SKILL.md` at line 298, Update the
migration checklist wording around the stock feature inventory so it still
audits all 16 available features, but instructs registering only those actually
used by the migrated table’s table, row, column, cell, and header code. Preserve
the opt-in nature of v9 features and avoid requiring unrelated registrations.

@KevinVandy
KevinVandy merged commit 0b29431 into beta Aug 1, 2026
10 checks passed
@KevinVandy
KevinVandy deleted the agent/cell-selection-subtraction branch August 1, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant